package com.jumi.microservice.rocketmq;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.order.ConsumeOrderContext;
import com.aliyun.openservices.ons.api.order.MessageOrderListener;
import com.aliyun.openservices.ons.api.order.OrderAction;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jumi.microservice.common.constant.DelFlag;
import com.jumi.microservice.config.UserCashConfig;
import com.jumi.microservice.constant.UserCashStatusEnum;
import com.jumi.microservice.constant.usercash.CashStatusEnum;
import com.jumi.microservice.constant.usercash.CashTypeEnum;
import com.jumi.microservice.domain.MessageTemplate;
import com.jumi.microservice.dto.wallet.api.WalletInOrOutRequest;
import com.jumi.microservice.entity.UserCash;
import com.jumi.microservice.enumerate.WalletTypeEnum;
import com.jumi.microservice.mapper.UserCashMapper;
import com.jumi.microservice.mapper.UserWalletMapper;
import com.jumi.microservice.rocketmq.domian.UserCashEvent;
import com.jumi.microservice.service.IWalletInOrOutService;
import com.jumi.microservice.yzhpay.constant.CheckNameEnum;
import com.jumi.microservice.yzhpay.constant.ConfigPath;
import com.jumi.microservice.yzhpay.constant.OrderPrefixEnum;
import com.jumi.microservice.yzhpay.constant.XmlData;
import com.jumi.microservice.yzhpay.dto.request.AlipayOrderRequest;
import com.jumi.microservice.yzhpay.dto.request.BankCardOrderRequest;
import com.jumi.microservice.yzhpay.dto.request.Request;
import com.jumi.microservice.yzhpay.dto.response.Response;
import com.jumi.microservice.yzhpay.util.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Scw
 * @date 2020-08-24 11:00
 */
@Service
public class UserCashCheckAllListener implements MessageOrderListener {
    @Resource
    private UserCashMapper userCashMapper;
    @Resource
    private UserWalletMapper userWalletMapper;
    @Resource
    SendMessageHandler sendMessageHandler;
    @Resource
    private RedisTemplate<String,String> redisTemplate;
    @Resource
    private UserCashConfig userCashConfig;
    @DubboReference
    IWalletInOrOutService iWalletInOrOutService;

    private static final String key = "UserCashCheckAll::";

    private static final Logger log = LoggerFactory.getLogger(UserCashCheckAllListener.class);

    @Override
    public OrderAction consume(Message message, ConsumeOrderContext consumeOrderContext) {
        UserCashEvent userCashEvent;
        try {
            String messageStr = new String(message.getBody());
            log.info("UserCashCheckAll--收到message：[{}]", messageStr);
            userCashEvent = JSONObject.parseObject(messageStr, UserCashEvent.class);
        } catch (Exception e) {
            log.error("UserCashCheckAll--出错：[{}]", e.getMessage());
            return OrderAction.Success;
        }
        log.info("UserCashCheckAll--收到消息 UserCashId：[{}]", userCashEvent.getUserCashId());
        Boolean res = redisTemplate.opsForValue().setIfAbsent(key+userCashEvent.getUserCashId(),"UserCashCheckAll",7, TimeUnit.DAYS);
        if(res!=null && !res){
            log.info("UserCashCheckAll重复，UserCashId：[{}]", userCashEvent.getUserCashId());
            return OrderAction.Success;
        }
        this.checkAgree(userCashEvent);
        return OrderAction.Success;
    }

    /**
     * 审核同意并打款
     * 打款失败，资金返还钱包
     */
    private void checkAgree(UserCashEvent userCashEvent) {
        Integer userCashId = userCashEvent.getUserCashId();
        Long operatorId = userCashEvent.getLoginId();
        String operatorName = userCashEvent.getLoginName();
        //查询当前信息
        if (userCashId > 0) {
            //查询信息
            QueryWrapper<UserCash> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", UserCashStatusEnum.STATUS_APPLY.getCode());
            queryWrapper.eq("del_flag", DelFlag.NORMAL);
            queryWrapper.eq("id", userCashId);
            UserCash userCash = userCashMapper.selectOne(queryWrapper);
            if (userCash != null) {
                // 改变状态、记录原因
                int checkStatus = UserCashStatusEnum.CHECK_STATUS_PASSED.getCode();
                userCash.setId(userCashId);
                userCash.setStatus((byte) checkStatus);
                userCash.setCheckTime(new Date());
                userCash.setCheckOperatorId(operatorId);
                userCash.setCheckOperatorName(operatorName);
                int resCheck = userCashMapper.updateById(userCash);
                if (resCheck > 0) {
                    MessageTemplate messageTemplate = sendMessageHandler.getMessageTemplate(19);
                    String appMessageContent = messageTemplate.getSmtAppContent();
                    String stationMessageContent = messageTemplate.getSmtMessageContent();
                    sendMessageHandler.sendMessage(appMessageContent,stationMessageContent,userCash.getUid(),19);
                    this.batchPay(userCashId);
                }
            }
        }
    }

    /**
     * 云账户
     * 公共返回方法
     */
    public Map<String, String> sysoutResult(Map<String, Object> result) {
        Map<String, String> returnMap = new HashMap<>();
        String statusCode = StringUtils.trim(result.get(XmlData.STATUSCODE));
        String dataJson;
        String yzhCode = "";
        String yzhData = "";
        String yzhMessage = "";
        String yzhRequestId = "";
        if ("200".equals(statusCode)) {
            dataJson = StringUtils.trim(result.get(XmlData.DATA));
            Response response = JsonUtil.fromJson(dataJson, Response.class);
            if (response != null) {
                yzhCode = response.getCode();
                if (response.getData() != null) yzhData = JSON.toJSONString(response.getData());
                yzhMessage = response.getMessage();
                yzhRequestId = response.getRequest_id();
            }
        }
        returnMap.put("statusCode", statusCode);
        returnMap.put("yzhCode", yzhCode);
        returnMap.put("yzhData", yzhData);
        returnMap.put("yzhMessage", yzhMessage);
        returnMap.put("yzhRequestId", yzhRequestId);
        return returnMap;
    }

    /**
     * 批量打款通用方法
     */
    private void batchPay(int userCashId) {
        //查询信息
        QueryWrapper<UserCash> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", CashStatusEnum.STATUS_AUDIT_PASSED.getCode());
        queryWrapper.eq("del_flag", DelFlag.NORMAL);
        queryWrapper.eq("id", userCashId);
        UserCash userCash = userCashMapper.selectOne(queryWrapper);
        if (userCash != null) {
            /**
             * 云账户
             * 个人银行卡
             */
            //公共信息
            String yzhMess = OrderUtil.getMess();
            int yzhTimestamp = Integer.parseInt(String.valueOf(System.currentTimeMillis() / 1000));
            String yzhSignType = Property.getProperties(ConfigPath.YZH_SIGN_TYPE);
            String yzhDealerId = Property.getProperties(ConfigPath.YZH_DEALERID);
            String yzhBrokerId = Property.getProperties(ConfigPath.YZH_BROKERID);
            if (userCash.getCashType() == CashTypeEnum.CASH_BANKCARD.getCode().byteValue()) {
            /*
             * ⾃动和实时结算⾄银⾏卡
             * 转账给个⼈银⾏卡账户，通道限制单笔最低0.01
             * 银⾏卡通道单笔⽀付有0.5元成本（成本由云账户承担），建议商户单笔银⾏卡付款⼤于
50元         */
                //银行卡
                String yzhOrderIdBankCard = OrderUtil.getOrderId(OrderPrefixEnum.BANK_CARD_ORDER.getValue());
                //String yzhNotifyUrlBankCard = Property.getProperties(ConfigPath.YZH_BACKNOTIFY_URL);
                String yzhNotifyUrlBankCard = userCashConfig.getYzhBackNotify();
                String yzhGetUrlBankCard = Property.getUrl(ConfigPath.YZH_BANK_CARD_REAL_TIME_ORDER);
                //姓名、身份证号、银行卡号、实际到账金额
                String yzhRealName = userCash.getCashUserName();
                String yzhCardNo = userCash.getCashAccount();
                String yzhPhoneNo = "";
                String yzhIdCard = userCash.getCashIdCard();
                String yzhPay = userCash.getCashAmount().toString();
                String yzhPayRemark = "银⾏卡实时下单";

                Map<String, Object> yzhResultBankCard = null;
                try {
                    yzhResultBankCard = HttpUtil.post(
                            Request.builder()
                                    .mess(yzhMess)
                                    .timestamp(yzhTimestamp)
                                    .sign_type(yzhSignType)
                                    .build().encData(
                                    BankCardOrderRequest.builder()
                                            .order_id(yzhOrderIdBankCard)
                                            .dealer_id(yzhDealerId)
                                            .broker_id(yzhBrokerId)
                                            .real_name(yzhRealName)
                                            .card_no(yzhCardNo)
                                            .phone_no(yzhPhoneNo)
                                            .id_card(yzhIdCard)
                                            .pay(yzhPay)
                                            .pay_remark(yzhPayRemark)
                                            .notify_url(yzhNotifyUrlBankCard)
                                            .build()
                            ), yzhGetUrlBankCard);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //公共返回方法
                Map<String, String> returnMap = sysoutResult(yzhResultBankCard);
                //支付状态
                int payStatus;
                //支付返回码描述
                String payMsg;
                //云账户订单号
                String payNo="";
                //网关返回码
                String gatewayCode;
                //网关返回码描述
                String gatewayMsg;
                String statusCode = returnMap.get("statusCode");
                String yzhCode = returnMap.get("yzhCode");
                String yzhData = returnMap.get("yzhData");
                String yzhMessage = returnMap.get("yzhMessage");
                String yzhRequestId = returnMap.get("yzhRequestId");
                String parameters = "商户订单号：" + yzhOrderIdBankCard + " , 用户姓名：" + yzhRealName + " , 银行卡帐号: " + yzhCardNo + " , 手机号: " + yzhPhoneNo + " , 身份证号: " + yzhIdCard + " , 提现金额: " + yzhPay + " , 备注信息: " + yzhPayRemark;
                if ("200".equals(statusCode)) {
                    gatewayCode = statusCode;
                    gatewayMsg = "请求成功";
                    payStatus = CashStatusEnum.STATUS_AUDIT_PASSED.getCode();
                    payMsg = "网关返回码：" + gatewayCode + " , 网关返回码描述：" + gatewayMsg + " , 请求ID：" + yzhRequestId + " , 请求返回码：" + yzhCode + " , 请求返回码描述: " + yzhMessage;
                    if ("0000".equals(yzhCode)) {
                        JSONObject jsonObject = JSON.parseObject(yzhData);
                        payMsg += " , 【商户订单号：" + jsonObject.get("order_id") + " , 综合服务平台流水号: " + jsonObject.get("ref") + " , 提现金额: " + jsonObject.get("pay") + "】";
                        payNo = jsonObject.get("order_id").toString();
                    }
                } else {
                    gatewayCode = statusCode;
                    gatewayMsg = "请求异常，请联系管理员";
                    payStatus = CashStatusEnum.STATUS_CASH_FAILED.getCode();
                    payMsg = "网关返回码：" + gatewayCode + " , 网关返回码描述：" + gatewayMsg;
                    //返还金额到钱包
//                    UserWallet userWallet = new UserWallet();
//                    userWallet.setUserId(userCash.getUid());
//                    userWallet.setType(WalletTypeEnum.FAIL_WITHDRAW_IN.getCode());
//                    userWallet.setAmount(userCash.getCashAmount());
//                    userWallet.setRemark(WalletTypeEnum.FAIL_WITHDRAW_IN.getMsg());
//                    userWallet.setOrderId(userCashId);
//                    userWallet.setOrderNo(userCash.getOrderNo());
//                    userWalletMapper.insert(userWallet);
                    WalletInOrOutRequest walletInOrOutRequest = new WalletInOrOutRequest();
                    walletInOrOutRequest.setAmount(userCash.getCashAmount());
                    walletInOrOutRequest.setRemark(WalletTypeEnum.FAIL_WITHDRAW_IN.getMsg());
                    walletInOrOutRequest.setUserId(userCash.getUid());
                    walletInOrOutRequest.setType(WalletTypeEnum.FAIL_WITHDRAW_IN.getCode());
                    walletInOrOutRequest.setOrderNo(userCash.getOrderNo());
                    walletInOrOutRequest.setOrderId(userCashId);
                    iWalletInOrOutService.walletIn(walletInOrOutRequest);
                }
                // 更新支付状态
                userCash.setStatus((byte) payStatus);
                userCash.setPayTime(new Date());
                userCash.setPayCode(yzhCode);
                userCash.setPayMsg(payMsg);
                userCash.setPayNo(payNo);
                userCash.setParameters(parameters);
                userCash.setGatewayCode(gatewayCode);
                userCash.setGatewayMsg(gatewayMsg);
                userCash.setCashAccount(yzhCardNo);
                userCash.setCashUserName(yzhRealName);
                userCashMapper.updateById(userCash);
            } else if (userCash.getCashType() == CashTypeEnum.CASH_ALIPAY.getCode().byteValue()) {
                //支付宝
                String yzhOrderIdAlipay = OrderUtil.getOrderId(OrderPrefixEnum.ALIPAY_ORDER.getValue());
                //String yzhNotifyUrlAlipay = Property.getProperties(ConfigPath.YZH_BACKNOTIFY_URL);
                String yzhNotifyUrlAlipay = userCashConfig.getYzhBackNotify();
                String yzhGetUrlAlipay = Property.getUrl(ConfigPath.YZH_ALIPAY_REAL_TIME_ORDER);
                String yzhCheckName = CheckNameEnum.NOCHECK.getValue();
                //姓名、身份证号、支付宝帐号、实际到账金额
                String yzhRealName = userCash.getCashUserName();
                String yzhIdCard = userCash.getCashIdCard();
                String yzhCardNo = userCash.getCashAccount();
                String yzhPay = userCash.getCashAmount().toString();
                String yzhPayRemark = "支付宝实时下单";

                //支付宝
                Map<String, Object> yzhResultAlipay = null;
                try {
                    yzhResultAlipay = HttpUtil.post(
                            Request.builder()
                                    .mess(yzhMess)
                                    .timestamp(yzhTimestamp)
                                    .sign_type(yzhSignType)
                                    .build().encData(
                                    AlipayOrderRequest.builder()
                                            .order_id(yzhOrderIdAlipay)
                                            .dealer_id(yzhDealerId)
                                            .broker_id(yzhBrokerId)
                                            .real_name(yzhRealName)
                                            .card_no(yzhCardNo)
                                            .id_card(yzhIdCard)
                                            .pay(yzhPay)
                                            .pay_remark(yzhPayRemark)
                                            .check_name(yzhCheckName)
                                            .notify_url(yzhNotifyUrlAlipay)
                                            .build()
                            ), yzhGetUrlAlipay);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //公共返回方法
                Map<String, String> returnMap = sysoutResult(yzhResultAlipay);
                //支付状态
                int payStatus;
                //支付返回码描述
                String payMsg;
                //云账户订单号
                String payNo="";
                //网关返回码
                String gatewayCode;
                //网关返回码描述
                String gatewayMsg;
                String statusCode = returnMap.get("statusCode");
                String yzhCode = returnMap.get("yzhCode");
                String yzhData = returnMap.get("yzhData");
                String yzhMessage = returnMap.get("yzhMessage");
                String yzhRequestId = returnMap.get("yzhRequestId");
                String parameters = "商户订单号：" + yzhOrderIdAlipay + " , 用户姓名：" + yzhRealName + " , 收款人支付宝账户: " + yzhCardNo + " , 身份证号: " + yzhIdCard + " , 提现金额: " + yzhPay + " , 备注信息: " + yzhPayRemark;
                if ("200".equals(statusCode)) {
                    gatewayCode = statusCode;
                    gatewayMsg = "请求成功";
                    payStatus = CashStatusEnum.STATUS_AUDIT_PASSED.getCode();
                    payMsg = "网关返回码：" + gatewayCode + " , 网关返回码描述：" + gatewayMsg + " , 请求ID：" + yzhRequestId + " , 请求返回码：" + yzhCode + " , 请求返回码描述: " + yzhMessage;
                    if ("0000".equals(yzhCode)) {
                        JSONObject jsonObject = JSON.parseObject(yzhData);
                        payMsg += " , 【商户订单号：" + jsonObject.get("order_id") + " , 综合服务平台流水号: " + jsonObject.get("ref") + " , 提现金额: " + jsonObject.get("pay") + "】";
                        payNo = jsonObject.get("order_id").toString();
                    }
                } else {
                    gatewayCode = statusCode;
                    gatewayMsg = "请求异常，请联系管理员";
                    payStatus = CashStatusEnum.STATUS_CASH_FAILED.getCode();
                    payMsg = "网关返回码：" + gatewayCode + " , 网关返回码描述：" + gatewayMsg;
                    //返还金额到钱包
//                    UserWallet userWallet = new UserWallet();
//                    userWallet.setUserId(userCash.getUid());
//                    userWallet.setType(WalletTypeEnum.FAIL_WITHDRAW_IN.getCode());
//                    userWallet.setAmount(userCash.getCashAmount());
//                    userWallet.setRemark(WalletTypeEnum.FAIL_WITHDRAW_IN.getMsg());
//                    userWallet.setOrderId(userCashId);
//                    userWallet.setOrderNo(userCash.getOrderNo());
//                    userWalletMapper.insert(userWallet);
                    WalletInOrOutRequest walletInOrOutRequest = new WalletInOrOutRequest();
                    walletInOrOutRequest.setAmount(userCash.getCashAmount());
                    walletInOrOutRequest.setRemark(WalletTypeEnum.FAIL_WITHDRAW_IN.getMsg());
                    walletInOrOutRequest.setUserId(userCash.getUid());
                    walletInOrOutRequest.setType(WalletTypeEnum.FAIL_WITHDRAW_IN.getCode());
                    walletInOrOutRequest.setOrderNo(userCash.getOrderNo());
                    walletInOrOutRequest.setOrderId(userCash.getId());
                    iWalletInOrOutService.walletIn(walletInOrOutRequest);
                }
                // 更新支付状态
                userCash.setStatus((byte) payStatus);
                userCash.setPayTime(new Date());
                userCash.setPayCode(yzhCode);
                userCash.setPayMsg(payMsg);
                userCash.setPayNo(payNo);
                userCash.setParameters(parameters);
                userCash.setGatewayCode(gatewayCode);
                userCash.setGatewayMsg(gatewayMsg);
                userCash.setCashAccount(yzhCardNo);
                userCash.setCashUserName(yzhRealName);
                userCashMapper.updateById(userCash);
            }
        }
    }

}
